package com.himiotech.core.framework.config.async;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.himiotech.core.framework.helper.constant.Constants;
import com.himiotech.core.framework.helper.constant.UserConstants;
import com.himiotech.core.framework.helper.utils.HimioUtils;
import com.himiotech.core.framework.helper.utils.ServletUtils;
import com.himiotech.core.framework.helper.utils.ShiroUtils;
import com.himiotech.core.framework.helper.utils.SpringUtils;
import com.himiotech.core.project.model.entity.LoginInfo;
import com.himiotech.core.project.model.entity.OperateLog;
import com.himiotech.core.project.model.entity.online.OnlineSession;
import com.himiotech.core.project.model.entity.online.UserOnline;
import com.himiotech.core.project.service.ILoginInfoService;
import com.himiotech.core.project.service.IOperateLogService;
import com.himiotech.core.project.service.IUserOnlineService;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.TimerTask;

/**
 * 异步工厂（产生任务用）
 *
 * @author liuhulu
 * @author wuwenbin
 */
@Slf4j
public class AsyncFactory {

    /**
     * 同步session到数据库
     *
     * @param session 在线用户会话
     * @return 任务task
     */
    public static TimerTask syncSessionToDb(final OnlineSession session) {
        return new TimerTask() {
            @Override
            public void run() {
                UserOnline online = new UserOnline();
                online.setSessionId(String.valueOf(session.getId()));
                online.setDeptName(session.getDeptName());
                online.setLoginName(session.getLoginName());
                online.setStartTimestamp(session.getStartTimestamp());
                online.setLastAccessTime(session.getLastAccessTime());
                online.setExpireTime(session.getTimeout());
                online.setIpAddr(session.getHost());
                online.setLoginLocation(HimioUtils.getRealAddressByIp(session.getHost()));
                online.setBrowser(session.getBrowser());
                online.setOs(session.getOs());
                online.setStatus(session.getStatus());
                online.setSession(session);
                HimioUtils.checkShiroSecurityManager();
                try {
                    SpringUtils.getBean(IUserOnlineService.class).saveOnline(online);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("同步 session 失败==>：" + e.getMessage());
                }
            }
        };
    }

    /**
     * 操作日志记录
     *
     * @param operateLog 操作日志信息
     * @return 任务task
     */
    public static TimerTask recordOperateLog(final OperateLog operateLog) {
        return new TimerTask() {
            @Override
            public void run() {
                // 远程查询操作地点
                operateLog.setOperateLocation(HimioUtils.getRealAddressByIp(operateLog.getOperateIp()));
                operateLog.setOperateTime(new Date());
                HimioUtils.checkShiroSecurityManager();
                try {
                    SpringUtils.getBean(IOperateLogService.class).save(operateLog);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("记录操作日志失败 ==> ：" + e.getMessage());
                }
            }
        };
    }

    /**
     * 记录登录信息
     *
     * @param username 用户名
     * @param status   状态
     * @param message  消息
     * @param args     列表
     * @return 任务task
     */
    public static TimerTask recordLoginInfo(final String username, final String status, final String message, final Object... args) {
        final UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
        final String ip = ShiroUtils.getIp();
        return new TimerTask() {
            @Override
            public void run() {
                String address = HimioUtils.getRealAddressByIp(ip);
                // 打印信息到日志
                String s = StrUtil.format("[{}]", ip) +
                        address +
                        StrUtil.format("[{}]", username) +
                        StrUtil.format("[{}]", status) +
                        StrUtil.format("[{}]", message);
                log.info(s, args);
                // 获取客户端操作系统
                String os = userAgent.getOs().getName();
                // 获取客户端浏览器
                String browser = userAgent.getBrowser().getName();
                // 封装对象
                LoginInfo loginInfo = new LoginInfo();
                loginInfo.setLoginName(username);
                loginInfo.setIpAddr(ip);
                loginInfo.setLoginLocation(address);
                loginInfo.setBrowser(browser);
                loginInfo.setOs(os);
                loginInfo.setMsg(message);
                loginInfo.setLoginTime(new Date());
                // 日志状态
                if (StrUtil.equalsAny(status, UserConstants.LOGIN_SUCCESS, UserConstants.LOGOUT, UserConstants.REGISTER)) {
                    loginInfo.setStatus(Constants.SUCCESS);
                } else if (UserConstants.LOGIN_FAIL.equals(status)) {
                    loginInfo.setStatus(Constants.FAIL);
                }

                HimioUtils.checkShiroSecurityManager();
                // 插入数据
                try {
                    SpringUtils.getBean(ILoginInfoService.class).save(loginInfo);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("记录登录日志失败==>：" + e.getMessage());
                }
            }
        };
    }

}
